iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 11
1

第十天,本系列文關於 Web Audio API 的部分也逐漸邁向尾聲。今天要介紹的是做頻譜分析、音檔視覺化必要的 AnalyserNode。

AnalyserNode

顧名思義,當然就是要玩音頻分析時用的,可以參照 MDN 的示意圖:

analyser

當訊號經過 Analyser 時,可以透過 API 內的函數取得 FFT 資料。FFT 指的是 快速傅立葉轉換 (Fast Fourier Transform),用途是讓資料在 時域與頻域 之相互轉換。

筆者想起以前電機系的回憶了 (泣

這邊時域與頻率的轉換,指的是將複雜的訊號,換算成數個不同頻率、不同振幅的弦波的互相疊加,如圖所示:
FFT

透過 Analyser,我們可以簡單快速的取得 FFT 轉換後的資料;若將這些資料做些簡單的圖像呈現,也就成為大家熟悉的 頻譜分析圖囉。

那麼,今天的範例就來玩玩看 2D 的頻譜分析圖吧~

Demo

昨天的範例,已經把麥克風收音的授權、串流處理函式等部分完成了;今天的重點就是 AnalyserNode 的實際應用。

一如往常,首先還是先建立 AnalyserNode 實例:

const analyser = audioCtx.createAnalyser()

並指定 analyser 一個 Frame (樣本群) 的大小:

analyser.fftSize = 1024

所謂樣本群,指的是在聲音轉成數位訊號的過程中,由於電腦無法真正的紀錄連續訊號,需要先經過 採樣 的過程,將連續訊號轉成離散訊號。一個 Frame 的大小,也就是設定一個樣本群要有幾個取樣結果。可以參考下圖:

FFT

圖片摘自 演算法筆記

在串流處理函式內,將麥克風與 AnalyserNode 透過 connect 連接:

getUserMic(stream) {
  this.micStream = stream
  this.source = this.audioCtx.createMediaStreamSource(stream)
  this.source.connect(this.analyser)
},

當使用者按下 Play 時,透過 windows.requestAnimationFrame,反覆呼叫 analyser 取得 FFT 後的資料:

play() {
  this.isPlaying = true
  this.gainNode.connect(this.audioCtx.destination)
  requestAnimationFrame(this.getFFTData)
},
getFFTData(){
  this.fftArray = new Uint8Array(this.analyser.fftSize)
  this.analyser.getByteFrequencyData(this.fftArray)
  if (this.isPlaying) requestAnimationFrame(this.getFFTData)
}

這邊宣告了一組 Uint8Array,用來承接 analyser.getByteFrequencyData後的資料。

到這邊就取得資料啦!接著要把資料呈現出來。
先很直觀的透過迴圈做一堆 div,並透過資料綁定來設定元素高度:

<div class="result">
  <div class="fftData" v-for="n in 512" 
    :key="n" 
    :style="{'height': fftArray[(n-1)]+2 + 'px'}" 
  />
</div>

最後是排版一下,調成喜歡的樣子,就完成啦~

Live Demo

result

看到成品真的好感動啊!透過 Web Audio API,就可以簡單快速的做出頻譜分析,真的是成就感滿滿!

今天就先這樣囉~

筆者

Gary

半路出家網站工程師;半生熟的前端加上一點點的後端。
喜歡音樂,喜歡學習、分享,也喜歡當個遊戲宅。

相信一切安排都是最好的路。


上一篇
09. Web Audio API - 音源 Part.2
下一篇
11. 吉他調音器 Part.1
系列文
JavaScript 音樂漫遊 - 30 天探索 Web Audio!31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言